<template>
	<view class="test-detail">
		<scroll-view scroll-y class="scroll-spell" v-if="!visibleStudyWord" :class="spellCls">
			<view class="word-mean">{{mean}}<u-icon name="volume" class="play ml-5px" color="#5f5d5d" size="50" @click="playMp3(current?.MP3)"></u-icon></view>
			<view class="spell-input-box">
				<template v-for="(item, _index) in spellInputItems" :key="_index">
					<view
						v-if="item.input !== ' '"
						class="spell-input"
						:class="{
							spell: item.spell,
							success: item.class === 'success',
							error: item.class === 'error',
							...(item.syclass ? { [item.syclass]: true } : {})
						}"
						:style="item.minlen ? 'min-width:' + (item.minlen*22) + 'px': ''"
						@tap="handleCleanInput(item)"
					>{{ item.input }}</view>
					<view v-else class="spell-input w-40rpx"></view>
				</template>
				<view v-if="!commitEnable" class="spell-reset" @tap="handleClear()" >重置</view>
			</view>
			<view style="display: flex;justify-content: center;margin-top: 100rpx;" v-if="!commitEnable">
				<view class="spell-origin-box" :style="spellItems.length>4?'justify-content: flex-start': ''">
					<template v-for="(item, _index) in spellItems" :key="item.letter + _index">
						<view class="spell-origin" :style="item.show?'':'visibility: hidden'" @tap="handleToInput(item)" >{{item.letter}}</view>
					</template>
				</view>
			</view> 
			<!-- <view v-if="commitEnable" style="text-align: center;font-size: 80rpx;background-color: rgba(90,199,37,0.5); border: 1px solid #5AC725; color: #fff;">{{current.Word}}</view> -->
			<view v-if="commitEnable" style="text-align: center;font-size: 80rpx; margin-top: 20rpx;margin-bottom: 20px;">{{current?.Word}}</view>
			<sentence-linght-words v-if="commitEnable && current?.SentenceSnapshot" class="mt-10px text-center" :words="current" :sentence="current?.SentenceSnapshot" />
			<view class="mt-10px text-center">
				{{current?.SentenceSnapshot.SentenceCn}}
			</view>
			<view class="text-18 jump" style="display: flex;text-align: center; margin-top:20px;">
				<view class="text-16" style="flex:1; color: #777;padding:10px;">
					<text v-if="jump && !commitEnable"   @click="handleJump" style="">跳过</text>
					<text v-if="showTimer && !commitEnable && state.countdown>0" style="padding-left:10px;">({{state.countdown}})</text>
				</view> 
			</view>
			<u-image class="sentence-img" height="250rpx" v-if="commitEnable && current?.SentenceSnapshot.Media" :src="current?.SentenceSnapshot.Media" mode="aspectFit"></u-image>
		</scroll-view>
		<study-word v-else :current="current"></study-word>
		<view class="btn-box bottom-btn-box">
			<u-button @click="handleCommit" v-if="visibleCommit" class="next-btn" type="warning" :plain="true">
				<view class="next-text">提交</view>
			</u-button>
			<u-button @click="visibleStudyWord=true" v-if="visibleViewWord" class="next-btn" type="warning" :plain="true">
				<view class="next-text">查看</view>
			</u-button>
			<view style="width: 20rpx;" v-if="visibleViewWord && visibleNext"></view>
			<u-button @click="gonext" v-if="visibleNext" class="next-btn" type="warning" :plain="true">
				<view class="next-text">继续</view>
			</u-button>
		</view>
	</view>
</template>

<script lang="ts" setup>
	import { ref, defineExpose, onMounted, computed, defineModel, nextTick, onUnmounted, watch, inject } from 'vue';
	import { TestTemplate, IWord, TestTemplates, useStudyStore } from '@/store/study';
	import { createOptionsMixins, randomArray, isEmpty, isEmptyObj } from '@/utils';
	import { useSoundEffect, useTest, useTimer } from '@/common/hooks';
	import SentenceLinghtWords from '../sentence-linght-words/sentence-linght-words.vue';
	import StudyWord from '../study-word/study-word.vue';
	
	/** 组件参数类型 */
	type IProps = {
		/** 做题模式 */
		type?: { template: TestTemplate };
		/** 当前测试词汇 */
		current?: IWord;
		/** 是否开启氛围模式 */
		effect?: boolean;
		/** 是否开启跳过模式 */
		jump?: boolean;
		/** 是否开启答题错误进入词汇学习模式 */
		errLearn?: boolean;
		/** 计时器状态栏样式 */
		timerBarSty?: string;
		/** 是否开启计时器 */
		showTimer?: boolean;
	}
	type SpellItem = { letter: string; show: boolean; }
	type SpellInput = { input: string; spell: boolean; spellItem?: SpellItem; class?: string, [key: string]: any }
	
	/** 单词拼写组件 */
	defineOptions({
		name: 'spell-word',
		inheritAttrs: false,
		options: {
			virtualHost: true
		}
	});
	// 声明组件基本要素
	const props = withDefaults(defineProps<IProps>(), {
		current: () => null,
		jump: false,
		effect: false,
		errLearn: false,
		timerBarSty: '',
		showTimer: false
	});
	const modelValue = defineModel<boolean>('value', { default: false }); // v-model:value
	const emit = defineEmits(['next'])
	
	const isteacher = inject('isteacher');
	const isreview = inject('isreview');
	
	// 初始化hooks
	const studyStore = useStudyStore();
	const testUtil = useTest();
	const { state, startDownTime, clearTimer } = useTimer();
	const { playMp3, palySuccessMp3, playFailMp3 } = useSoundEffect();
	
	// 声明用户变量
	const spellInputItems = ref<SpellInput[]>([]);
	const spellItems = ref<SpellItem[]>([]);
	// 是否已经提交过
	const commitEnable = ref(false);
	// 学习界面显示状态
	const visibleStudyWord = ref(false);
	// 首次填充完毕状态
	const firstFillCompleted = ref(false);
	
	const spellCls = computed(() => {
		const hasBtn = visibleCommit.value || visibleViewWord.value || visibleNext.value;
		if (!isteacher && !isreview) {
			if (hasBtn) {
				return 'teacher-remeber-spell has-btn';
			}
			return 'teacher-remeber-spell';
		}
		if (isteacher && isreview) {
			if (hasBtn) {
				return 'teacher-review-spell has-btn';
			}
			return 'teacher-review-spell';
		}
		if (isreview) {
			if (hasBtn) {
				return 'review-spell has-btn';
			}
			return 'review-spell';
		}
		return ''
	})
	
	const mean = computed(() => {
		if(props.current){
			return props.current.Mean
		}
		return ''
	})
	
	// 单词学习按钮显示状态
	const visibleViewWord = computed(() => {
		// 未初始化数据时，不显示
		if (spellInputItems.value.length === 0) return false;
		// 未开启答题错误进入词汇学习模式，不显示
		if (!props.errLearn) return false;
		// 未提交过，不显示
		if (!commitEnable.value) return false;
		// 已经是查看状态，不显示
		if (visibleStudyWord.value) return false;
		return true;
	})
	// 提交按钮显示状态
	const visibleCommit = computed(() => {
		// 未初始化数据时，不显示
		if (spellInputItems.value.length === 0) return false;
		// 倒计时归零时，不显示
		if(props.showTimer) {
			if (state.value.countdown === 0) return false;
		}
		// 已经提交过了，不显示
		if (commitEnable.value) return false;
		// 显示学习界面时，不显示
		if (visibleStudyWord.value) return false;
		// 当首次填充完毕过后，会显示提交按钮
		return firstFillCompleted.value;
	});
	// 继续按钮显示状态
	const visibleNext = computed(() => {
		// 未初始化数据时，不显示
		if (spellInputItems.value.length === 0) return false;
		// 已经提交过，才会显示
		return commitEnable.value;
	});

	// 拼写正确验证
	function validModelValue(needSetFirstFillDone: boolean = true) {
		const { Word } = props.current;
		const spellWordText = spellInputItems.value.map(inputItem => inputItem.input).join('');
		modelValue.value = Word === spellWordText;
		
		if (needSetFirstFillDone) {
			// 首次填充完毕状态更新
			const isDone = !spellInputItems.value.some(item => item.spell && item.input === '');
			if (isDone) {
				firstFillCompleted.value = true;
			}
		}
	}
	
	function handleClear(){
		if(commitEnable.value) return;
		spellInputItems.value.forEach(item => {
			if(item.spell){
				item.spellItem = null;
				item.input = '';
			}
		})
		spellItems.value.forEach(item => {
			item.show = true
		})
	}
	// 拼写填入
	function handleToInput(letterItem: SpellItem) {
		if (props.showTimer) {
			// 倒计时归零了，停止答题操作
			if (state.value.countdown === 0) return;
		}
		
		// 已经提交答题，停止答题操作
		if (commitEnable.value) return;
		
		for (let i = 0; i < spellInputItems.value.length; i++) {
			if (!spellInputItems.value[i].input) {
				spellInputItems.value[i].input = letterItem.letter;
				letterItem.show = false;
				spellInputItems.value[i].spellItem = letterItem;
				break;
			}
		}
		
		validModelValue();
	}
	// 清理填入内容
	function handleCleanInput(item: SpellInput) {
		// 倒计时归零了，停止答题操作
		if (props.showTimer) {
			if (state.value.countdown === 0) return;
		}
		
		// 已经提交答题，停止答题操作
		if (commitEnable.value) return;
		
		item.input = '';
		if (item.spellItem) {
			item.spellItem.show = true;
			item.spellItem = null;	
		}
		
		modelValue.value = false;
	}
	
	// 初始化全拼数据
	function initFillData() {
		const { Word, Syllable } = props.current;
		const letterList: SpellItem[] = [];
		const spellInputList: SpellInput[] = [];
		
		let sy = [];
		if (!/[^a-zA-Z]/.test(Word) && Syllable) {
			if (Syllable.includes('/') && Syllable.replace(/\//g,'') === Word) {
				sy = Syllable.split('/').flatMap((item, index) => {
					const arr = [];
					for (let i = 0; i < item.length; i++) {
						arr.push(index % 2 === 0 ? 'sy1' : 'sy2')
					}
					return arr;
				})
			}
		}
		for (let i = 0; i < Word.length; i++) {
			const char = Word.charAt(i);
			if (/^[A-Za-z]$/.test(char)) {
				letterList.push({ letter: char, show: true });
				if (sy.length > 0) {
					spellInputList.push({ input: '', spell: true, syclass: sy[i] })
				} else {
					spellInputList.push({ input: '', spell: true })
				}
			} else {
				spellInputList.push({ input: char, spell: false })
			}
		}
		spellItems.value = randomArray(letterList);
		spellInputItems.value = spellInputList;
	}
	// 初始化挖空拼写数据
	function initFillSimpleData() {
		const { Word } = props.current;
		const letterList: SpellItem[] = [];
		const spellInputList: SpellInput[] = [];
		let spellLetterCnt = Math.round((Word.length + 1) * 0.3); // 取字母个数
		if (spellLetterCnt > 2) {
		    spellLetterCnt = 2;
		}
		
		// 生成挖空的索引位置
		const fillWordIndexList = new Array(spellLetterCnt + 1).fill(null);
		for (let i = 0; i < spellLetterCnt; i++) {
		    const randomIndex = Math.floor(Math.random() * Word.length); // 随机取字母
		    if (!fillWordIndexList.includes(randomIndex)) {
		        if (/^[A-Za-z]$/.test(Word.charAt(randomIndex))) {
		            fillWordIndexList[i] = randomIndex;
					continue;
		        }
		    }
			i--;
		}
		
		for (let i = 0; i < Word.length; i++) {
			const char = Word.charAt(i);
			if (fillWordIndexList.includes(i)) {
				letterList.push({ letter: char, show: true });
				spellInputList.push({ input: '', spell: true });
			} else {
				spellInputList.push({ input: char, spell: false });
			}
		}
		
		// 加一些混淆项
		const ABCDEFG = ['a','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
		for (let i = 0; i < fillWordIndexList.length; i++) {
			letterList.push({ letter: randomArray(ABCDEFG)[0], show: true });
		}
		
		spellItems.value = randomArray(letterList);
		spellInputItems.value = spellInputList;
	}
	// 初始化音节拼写数据
	function initSyllableData() {
		const { Word, Syllable } = props.current;
		const syllableList: SpellItem[] = [];
		const spellInputList: SpellInput[] = [];
		
		// console.log('initSyllableData Word', Word)
		// console.log('initSyllableData Syllable', Syllable)
		
		let startLength = 0;
		Syllable.split('/').forEach((item, index, arr) => {
			// const minlen = arr.reduce((min, curr) => min < curr.length ? min : curr.length, item.length)
			const currentEndLength = startLength + item.length;
			const currentSpell = Word.substring(startLength, currentEndLength);
			syllableList.push({ letter: currentSpell, show: true });
			spellInputList.push({ input: '', spell: true, syclass: index % 2 === 0 ? 'sy1' : 'sy2', minlen: 3 })
			
			startLength += item.length;
		})
		
		spellItems.value = randomArray(syllableList);
		spellInputItems.value = spellInputList;
	}
	
	// 重置/初始化渲染
	function reset() {
		spellItems.value = [];
		spellInputItems.value = [];
		modelValue.value = false;
		commitEnable.value = false;
		visibleStudyWord.value = false;
		firstFillCompleted.value = false;
		
		if (!isEmptyObj(props.current)) {
			// 初始化拼写数据
			const { SPELL, SPELL_SIMPLE, SPELL_SYLLABLE } = TestTemplates;
			// console.log('spell-word  type', props.type)
			
			if(!testUtil.hasTemplate([SPELL, SPELL_SIMPLE, SPELL_SYLLABLE], props.type)) return;
			
			let dotime = 10;
			switch (testUtil.getTemplateType(props.type)) {
				case SPELL.type:
					initFillData();
					dotime = props.current.Word.length + 15;
					break;
				case SPELL_SIMPLE.type:
					initFillSimpleData();
					dotime = spellInputItems.value.filter(item => item.spell).length + 15;
					break;
				case SPELL_SYLLABLE.type:
					initSyllableData();
					dotime = spellInputItems.value.length + 15;
					break;
			}
			
			// console.log('spell-word >>> SPELL >>> playMp3', props.current.MP3)
			playMp3(props.current.MP3);
			
			if (props.showTimer) {
				// 开启倒计时
				startDownTime(dotime, () => {
					execSoundEffect();
					// 校验结果
					validModelValue(false);
					// 设置结果状态
					validResult();
					commitEnable.value = true;
				});
			}
		} else {
			spellItems.value = [];
		}
	}
	// 继续下一个单词测试
	function gonext() {
		emit("next", null, modelValue.value, false);
	}
	// 跳过事件
	function handleJump() {
		uni.showModal({
			content: '是否确认跳过?'
		}).then(res => {
			if(res.confirm){
				clearTimer(true);
				// visibleNext.value = false;
				spellItems.value = [];
				spellInputItems.value = [];
				emit("next", undefined, false, true);
			}
		})
	}
	function validResult() {
		spellInputItems.value.forEach((item, index) => {
			if (item.spell) {
				const type = testUtil.getTemplateType(props.type);
				const syllableType = TestTemplates.SPELL_SYLLABLE.type;
				let originLetter = '';
				if (type === syllableType) {
					originLetter = props.current.Syllable.split('/')[index];
				} else {
					originLetter = props.current.Word.charAt(index);
				}
				
				if (item.input !== originLetter) {
					item.class = 'error';
					// item.input = originLetter;
				} else {
					item.class = 'success';
				}
			}
		})
	}
	// 提交做题结果
	function handleCommit() {
		// 停止倒计时
		clearTimer();
		// 设置结果状态
		validResult();
		// 执行音效播放事件
		execSoundEffect();
		commitEnable.value = true;
	}
	// 执行音效播放事件
	function execSoundEffect() {
		if(modelValue.value){ 
			if(props.effect){
				palySuccessMp3();
			}
		} else { 
			if(props.effect){
				playFailMp3();
			}
		}
	}
	
	watch(() => [props.current, props.type], (nVal, oVal) => {
		clearTimer();
		// console.log('spell-word >>> watch >>> nVal[0] =', nVal[0])
		// console.log('spell-word >>> watch >>> oVal =', oVal)
		if(isEmptyObj(nVal[0])) return;
		// console.log('spell-word >>> 执行reset')
		reset();
	}, {
		immediate: true,
		deep: true
	})
	
	onUnmounted(() => {
		// console.log('onUnmounted >>> spell-word')
		clearTimer();
	})
	
</script>

<style lang="scss" scoped>
.test-detail {
	flex: none;
	
	.spell-reset{
		box-sizing: border-box;
		background-color: #fce2bf;
		color: var(--font-color);
		border-radius: 5px;
		display: flex;
		justify-content: center;
		align-items: center;
		padding: 6px 5px;
		margin-left: 5px;
	}
	
	/* #ifdef H5 */
	
	.teacher-remeber-spell { height: calc(100vh - 190px); }
	// .teacher-spell.has-btn { height: calc(100vh - 190px); }
	
	.teacher-review-spell { height: calc(100vh - 200px); }
	// .teacher-review-spell.has-btn { height: calc(100vh - 200px); }
	
	.review-spell { height: calc(100vh - 65px); }
	// .review-spell.has-btn { height: calc(100vh - 117px); }
	
	/* #endif */
	
	/* #ifdef MP */
	
	.teacher-remeber-spell { height: calc(100vh - 365rpx); }
	.teacher-remeber-spell.has-btn { height: calc(100vh - 445rpx); }
	
	.teacher-review-spell { height: calc(100vh - 170rpx); }
	.teacher-review-spell.has-btn { height: calc(100vh - 250rpx); }
	
	.review-spell { height: calc(100vh - 53rpx); }
	.review-spell.has-btn { height: calc(100vh - 136rpx); }
	
	/* #endif */
	
	.return-btn{
		position: absolute;
		left: 10px;
		top: -15px;
		z-index: 8;
	}
	.timer-btn{
		position: absolute;
		right: 10px;
		top: -15px;
		z-index: 8;
	}
	
	.spell-input-box{
		display: flex;
		align-items: center;
		justify-content: center;
		flex-wrap: wrap;
		
		.spell-input{
			display: flex;
			justify-content: center;
			align-items: center;
			font-size: 70rpx;
			margin-bottom: 20rpx;
			height: 100rpx;
		}
		.spell-input.spell{
			min-width: 70rpx;
			margin-left: 4rpx;
			margin-right: 4rpx;
			border-bottom: 2px solid #a1a1a1;
		}
		.spell-input.sy1{
			border-bottom: 2px solid #0f6ab1 !important;
			color: #0f6ab1;
		}
		.spell-input.sy2{
			border-bottom: 2px solid #f0ad4e !important;
			color: #f0ad4e;
		}
		.spell-input.success{ color: #5ac725 !important }
		.spell-input.error{ color: #ff0000 !important }
	}
	.spell-origin-box{
		--item-width: 70px;
		--item-half-margin: 5px;
		
		display: flex;
		align-items: center;
		justify-content: center;
		flex-wrap: wrap;
		box-sizing: border-box;
		width: calc((var(--item-width) + var(--item-half-margin)*2)*4);
		
		.spell-origin{
			height: var(--item-width);
			min-width: var(--item-width);
			font-size: 35px;
			box-sizing: border-box;
			margin: 0 var(--item-half-margin) 12px var(--item-half-margin);
			background-color: #fce2bf;
			color: var(--font-color);
			border-radius: 8px;
			display: flex;
			justify-content: center;
			align-items: center;
		}
	}
}

.btn-box{
	display: flex; align-items: center; 
}
.next-btn{
	width: 100% !important;
}
.next-text{
	font-size: var(--text-18);
	font-weight: bold;
	display: flex;
}

.word-mean{
	display: flex;
	justify-content: center;
	margin-bottom: 50rpx;
	font-size: 60rpx;
}

.sentence-img{
	margin-top: 10rpx;
}

/* 针对 1280px 分辨率 */
@media(min-width:1200px){
	.test-detail{
		.spell-input-box{
			.spell-input{
				height: 112rpx;
				min-width: 112rpx;
				margin: 0 45rpx;
				font-size: 60rpx;
			}
		}
		.spell-origin-box{
			margin-top: 160rpx;
			.spell-origin{
				height: 112rpx;
				min-width: 112rpx;
				margin: 0 45rpx;
				font-size: 60rpx;
			}
		}
	}
	
}
</style>